home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1996 June / EnigmA AMIGA RUN 08 (1996)(G.R. Edizioni)(IT)[!][issue 1996-06][EARSAN CD VII].iso / earcd / hardware / galer21.lha / GALer21 / Source / GALer / Port.asm < prev    next >
Assembly Source File  |  1996-04-05  |  49KB  |  1,667 lines

  1. *
  2. * This file is the interface between the software
  3. * and the hardware of GALer. The routines of this file
  4. * control the hardware.
  5. *
  6. * needed C-compiler optines: register parameter, 32 bit integer
  7. *
  8. * used assembler: asm of SAS/C 6.51
  9. *
  10. * assemble: asm Port.asm
  11. *
  12. * assumed scratch registers of the compiler: D0, D1, A0, A1
  13.  
  14.  
  15.  
  16.                 INCLUDE "hardware/cia.i"
  17.  
  18.  
  19. GAL16V8         EQU     1               ; type of GAL
  20. GAL20V8         EQU     2
  21. GAL22V10        EQU     3
  22. GAL20RA10       EQU     4
  23.  
  24.  
  25. IC1             EQU     3               ; number of IC
  26. IC2             EQU    11               ; IC2 only for elektor
  27. IC3             EQU     0               ; IC1-4       : write only
  28. IC4             EQU     1
  29. IC5             EQU     2
  30. IC6a            EQU     0               ; IC6, IC7: read only
  31. IC6c            EQU     4
  32. IC7             EQU     1
  33.  
  34.  
  35. HW_GALER_1_0    EQU     1               ; Hardware-Version
  36. HW_GALER_1_2    EQU     2
  37. HW_GALER_1_3    EQU     3
  38. HW_ELEKTOR_II   EQU    10
  39.  
  40. ON              EQU     1               ; for control of the LED
  41. OFF             EQU     0
  42.  
  43. PROG            EQU     1               ; Edit-Mode of GAL
  44. VERIFY          EQU     0
  45.  
  46. LOW             EQU     0               ; level
  47. HIGH            EQU     1
  48.  
  49.  
  50. ciab            EQU     $BFD000
  51.  
  52. ciaaprb         EQU     $BFE101
  53. ciaaddrb        EQU     $BFE301
  54. ciabpra         EQU     $BFD000
  55. ciabddra        EQU     $BFD200
  56.  
  57.  
  58.  
  59.  
  60.  
  61.  
  62.         SECTION code,CODE
  63.  
  64.  
  65.         XDEF    @InitParPort            ; initialize parallel port
  66.         XDEF    @RestoreParPort         ; restore parallel-port
  67.         XDEF    @InitHardware           ; initialize GAL programmer
  68.         XDEF    @WriteByte              ; write byte in shift register
  69.         XDEF    @ReadByte               ; read byte out of shift register
  70.         XDEF    @SetGAL                 ; set type of GAL
  71.         XDEF    @VeditOn                ; edit voltage on
  72.         XDEF    @VeditOff               ; disable edit off
  73.         XDEF    @LED                    ; control LED
  74.         XDEF    @EnableVcc              ; switch +5V on
  75.         XDEF    @DisableVcc             ; switch +5V off
  76.         XDEF    @EnableVEdit            ; enable edit voltage
  77.         XDEF    @DisableVEdit           ; disable edit voltage
  78.         XDEF    @EnableOutput           ; Ausgangs-Treiber aktivieren
  79.         XDEF    @DisableOutput          ; Ausgangs-Treiber deaktiviern
  80.         XDEF    @SetRow                 ; set address at RAG0-RAG5
  81.         XDEF    @SDIn                   ; set level of SDIn input
  82.         XDEF    @SDOut                  ; get level at SDOut output
  83.         XDEF    @Clock                  ; clock impuls at SCLK input
  84.         XDEF    @STRImpuls              ; make STR impuls
  85.         XDEF    @EditMode               ; set bits for edit mode
  86.         XDEF    @ExitEditMode           ; exit edit mode and switch off +5V
  87.         XDEF    @SetPV                  ; set PV (VERIFY or PROG)
  88.         XDEF    @SetVolt                ; set voltage for edit mode
  89.         XDEF    @SetPESSAVE             ; set level of PESSAVE pin
  90.         XDEF    @SetERASE               ; set level of ERASE pin
  91.         XDEF    @SetCLR                 ; set level of CLR pin
  92.         XDEF    @SetARCH                ; set level of ARCH pin
  93.         XDEF    @SetBE                  ; set level of BE pin
  94.         XDEF    @SetANDBE               ; set level of ANDBE pin
  95.         XDEF    @PollDelay              ; wait some micro seconds
  96.  
  97.         XDEF    _cia_timer_low
  98.         XDEF    _cia_timer_high
  99.         XDEF    _cia_timer_cr
  100.         XDEF    _cia_timer_start
  101.         XDEF    _cia_timer_stop
  102.         XDEF    _hw_version
  103.  
  104.  
  105.         XREF    _GALType
  106.         XREF    _outIC1
  107.         XREF    _outIC2
  108.         XREF    _outIC3
  109.         XREF    _outIC4
  110.         XREF    _outIC5
  111.  
  112.         XREF    @WaitForTimer
  113.  
  114.         XREF    _LVOForbid
  115.         XREF    _LVOPermit
  116.  
  117.         XREF    _prog_volt
  118.  
  119.  
  120.  
  121.  
  122.  
  123.  
  124. * initialize parallel port
  125. @InitParPort:
  126.         move.b  ciaaddrb,cia_addrb      ; save direction of CIAs
  127.         move.b  ciabddra,cia_bddra
  128.  
  129.         move.b  #%11111111,ciaaddrb     ; data as output
  130.         and.b   #%11111010,ciabddra     ; use BUSY as input
  131.                                         ; use SEL as input (for elektor`s
  132.         rts                             ; hardware)
  133.  
  134.  
  135.  
  136.  
  137.  
  138. * restore state of parallel port
  139. @RestoreParPort:
  140.         move.b  cia_addrb,ciaaddrb      ; Restore data direction of CIAs
  141.                                         ; but don't restore the state of
  142.         move.b  cia_bddra,d0            ; the outputs. Otherwise GALer could
  143.         and.b   #%11111010,ciabddra     ; get a command like Vcc or VEdit on.
  144.         and.b   #%00000101,d0
  145.         or.b    d0,ciabddra
  146.         rts
  147.  
  148.  
  149.  
  150.  
  151.  
  152. * initialize hardware: switch all outputs low
  153. * Parameter: none
  154. @InitHardware:
  155.         
  156.         cmp.l   #HW_ELEKTOR_II,_hw_version  ; which hardware version?
  157.         bne.s   ih_galer_hw
  158.                                             ; elektor hardware
  159.         moveq   #IC1,d1
  160.         moveq   #0,d0
  161.         bsr     @WriteByte
  162.  
  163.         moveq   #IC2,d1
  164.         moveq   #0,d0
  165.         bsr     @WriteByte
  166.  
  167.         moveq   #IC4,d1
  168.         moveq   #0,d0
  169.         bsr     @WriteByte
  170.         bra.s   ih_end
  171.  
  172.  
  173.                                             ; GALer hardware
  174. ih_galer_hw:
  175.         or.b    #%00001000,ciaaprb      ; PD3=H: Decoder deaktivieren!
  176.         and.b   #%00001000,ciaaprb      ; alle anderen Datenleitungen auf LOW
  177.                         ; ACHTUNG!!!: PD3 darf nur auf LOW-Pegel gehen
  178.                         ; (Decoder aktiviert werden), wenn durch PD0 und
  179.                         ; PD1 das IC, das angesprochen werden soll, bereits
  180.                         ; selektiert ist. Ansonsten bekommt ein IC einen Takt-
  181.                         ; impuls und beim nächsten Strobe liegen dann die
  182.                         ; falschen Daten an.
  183.         moveq   #IC1,d1
  184.         moveq   #0,d0
  185.         bsr     @WriteByte              ; Ausgänge von IC1 auf LOW      
  186.  
  187.         moveq   #IC3,d1
  188.         moveq   #0,d0
  189.         bsr     @WriteByte              ; Ausgänge von IC3 auf LOW      
  190.  
  191.         moveq   #IC4,d1
  192.         moveq   #0,d0
  193.         bsr     @WriteByte              ; Ausgänge von IC4 auf LOW      
  194.  
  195.         moveq   #IC5,d1
  196.         moveq   #0,d0
  197.         bsr     @WriteByte              ; Ausgänge von IC5 auf LOW      
  198.  
  199. ih_end: rts
  200.  
  201.  
  202.  
  203.  
  204.  
  205. * WriteByte:
  206. * write a byte "byte" into the IC "IC"
  207. * IC can be: GALer:   IC = IC1, IC3, IC4, IC5
  208. *            Elektor: IC = IC1, IC2, IC4
  209. * MSB is transfered first
  210. * call: WriteByte(byte, IC)
  211. @WriteByte:
  212.         movem.l d2/d3,-(sp)             ; save register
  213.                                         ; d0: data byte
  214.                                         ; d1: IC
  215.  
  216.         cmp.l   #IC1,d1                 ; save values which are to
  217.         bne.s   wb_1                    ; be written into the ICs
  218.         move.l  d0,_outIC1
  219.         bra.s   wb_c
  220. wb_1    cmp.l   #IC2,d1
  221.         bne.s   wb_2
  222.         move.l  d0,_outIC2
  223.         bra.s   wb_c
  224. wb_2    cmp.l   #IC3,d1
  225.         bne.s   wb_3
  226.         move.l  d0,_outIC3
  227.         bra.s   wb_c
  228. wb_3    cmp.l   #IC4,d1
  229.         bne.s   wb_4
  230.         move.l  d0,_outIC4
  231.         bra.s   wb_c
  232. wb_4    move.l  d0,_outIC5
  233. wb_c
  234.  
  235.         cmp.l   #HW_ELEKTOR_II,_hw_version  ; which hardware is connected?
  236.         bne.s   wb_galer_hw
  237.  
  238.                                 ;*** elektor hardware ***
  239.         
  240.                                 ; loading a shift register runs like this:
  241.                                 ;  1. store all 24 bit in a CPU-register
  242.                                 ;  2. shift them into the shift registers
  243.                                 ;  3. set STR of the shift register low to
  244.                                 ;     load them
  245.  
  246.         and.b   #%11110111,ciaaprb      ; set STR of the shift registers low
  247.  
  248.         move.l  _outIC2,d2              ; store the data of all shift
  249.         rol.l   #8,d2                   ; registers in d2
  250.         move.l  _outIC1,d3
  251.         move.b  d3,d2
  252.         rol.l   #8,d2
  253.         move.l  _outIC4,d3
  254.         move.b  d3,d2
  255.         rol.l   #8,d2
  256.  
  257.         moveq   #3*8-1,d3               ; loop counter: number of shift
  258.                                         ; registers 3; size 8 bit
  259.  
  260. wb_l1:  rol.l   #1,d2                   ; get MSB to bit 0
  261.         move.b  d2,d0
  262.         and.b   #%00000001,d0           ; get this bit in d0
  263.         and.b   #%11111110,ciaaprb      ; clear D0 of parallel port
  264.         or.b    d0,ciaaprb              ; set D0 according to this bit
  265.         or.b    #%00000010,ciaaprb      ; set CLK low
  266.         nop                             ; wait a little
  267.         nop
  268.         nop
  269.         and.b   #%11111101,ciaaprb      ; set CLK high
  270.         dbf     d3,wb_l1                ; shift 24 bits
  271.  
  272.         or.b    #%00001000,ciaaprb      ; set STR of the shift registers high
  273.         bra.s   wb_end
  274.  
  275.  
  276.  
  277. wb_galer_hw:                    ;*** GALer hardware ***
  278.  
  279.  
  280.         and.b   #%11111100,ciaaprb      ; PD0 und PD1 setzen (IC aus-
  281.         or.b    d1,ciaaprb              ; wählen)
  282.         and.b   #%11110111,ciaaprb      ; Decoder aktivieren
  283.  
  284.         moveq   #7,d3                   ; Schleifenzähler
  285.         ror.b   #3,d0                   ; MSB nach D4 (Datenleitung)
  286.  
  287. wb_l    move.b  d0,d2                   ; Datenbyte sichern
  288.         and.b   #%00010000,d2           ; Datenbit ausmaskieren
  289.         or.b    d2,ciaaprb              ; Datenbit (PD4) vom Par.-Port setzen
  290.  
  291.         or.b    #%00001000,ciaaprb      ; Clock-Impuls durch PD3 geben
  292.         and.b   #%11110111,ciaaprb      ; LOW-HIGH Übergang
  293.  
  294.         and.b   #%11101111,ciaaprb      ; Datenbit (PD4) auf LOW
  295.  
  296.         rol.b   #1,d0                   ; nächstniedrigeres Bit senden
  297.         dbf     d3,wb_l
  298.  
  299.         or.b    #%00001000,ciaaprb      ; Decoder wieder deaktivieren!!!
  300.                                         ; (sehr WICHTIG, siehe InitHardware)
  301.         or.b    #%00000100,ciaaprb      ; PD2 (Strobe) auf HIGH-> Daten werden
  302.         and.b   #%11111011,ciaaprb      ; vom Schieberegister in das Datenreg.
  303.                                         ; übernommen. Dann PD2 wieder auf LOW.
  304. wb_end  movem.l (sp)+,d2/d3
  305.         rts
  306.  
  307.  
  308.  
  309.  
  310.  
  311. * SetGAL:
  312. * define type of GAL (GAL16V8, GAL20V8, GAL22V10, GAL20RA10)
  313. * call: SetGAL(type);
  314. *
  315. @SetGAL:
  316.         move.l  d0,_GALType
  317.         rts
  318.  
  319.  
  320.  
  321.  
  322.  
  323. * VeditOn:
  324. * switch GALer's voltage converter on (IC9)
  325. * elektor's hardware does not support this, so just skip
  326. * call: VeditOn();
  327. @VeditOn:
  328.         cmp.l   #HW_ELEKTOR_II,_hw_version
  329.         beq.s   von_end
  330.  
  331.         move.l  #IC1,d1
  332.         or.l    #%00001,_outIC1         ; Q1 von IC1 auf HIGH => VeditOn
  333.         move.l  _outIC1,d0
  334.         bsr     @WriteByte              ; IC1 setzen
  335. von_end rts
  336.  
  337.  
  338.  
  339.  
  340.  
  341. * VeditOff:
  342. * switch GALer's voltage converter off (IC9)
  343. * elektor's hardware does not support his, so just skip
  344. * call: VeditOff();
  345. @VeditOff:
  346.         cmp.l   #HW_ELEKTOR_II,_hw_version
  347.         beq.s   voff_end
  348.  
  349.         move.l  #IC1,d1
  350.         and.l   #%11111110,_outIC1      ; Q1 von IC1 auf LOW => VeditOff
  351.         move.l  _outIC1,d0
  352.         bsr     @WriteByte              ; IC1 setzen
  353. voff_end
  354.         rts
  355.  
  356.  
  357.  
  358.  
  359.  
  360. * EnableVEdit:
  361. * switch edit voltage to pin 2 or pin 4 of the textool socket
  362. * (pin depends on selected type of GAL)
  363. * call: EnableVEdit();
  364. @EnableVEdit:
  365.  
  366.         cmp.l   #HW_ELEKTOR_II,_hw_version  ; which hardware is connected?
  367.         bne.s   ev_galer_hw
  368.                                 ;*** elektor hardware ***
  369.  
  370.         cmp.l   #GAL16V8,_GALType       ; 16V8 selected?
  371.         bne.s   ev_c1
  372.  
  373.         move.l  _outIC4,d0
  374.         and.l   #%11101111,d0
  375.         moveq   #IC4,d1
  376.         bsr     @WriteByte              ; set GAL16V8
  377.         bra.s   ev_c2
  378.  
  379. ev_c1                                   ; 20V8, 22V10, 20RA10 selected
  380.         move.l  _outIC4,d0
  381.         or.l    #%00010000,d0
  382.         moveq   #IC4,d1
  383.         bsr     @WriteByte              ; set GAL20V8 etc.
  384.  
  385. ev_c2
  386.         move.l  _outIC4,d0
  387.         or.l    #%00100000,d0
  388.         moveq   #IC4,d1
  389.         bsr     @WriteByte              ; enable edit voltage (IC3a)
  390.         bra.s   ev_end
  391.  
  392.  
  393.  
  394. ev_galer_hw                     ; *** GALer hardware ***
  395.  
  396.         moveq   #IC1,d1                 ; IC1 einstellen
  397.         cmp.l   #GAL16V8,_GALType       ; 16V8 eingestellt?
  398.         bne.s   eve_1                   ; nein, dann 20V8, 22V10, 20RA10
  399.  
  400.                                 ;*** GAL16V8 ***
  401.         moveq   #%00000100,d0           ; Q3 von IC1 auf HIGH
  402.         bra.s   eve_2
  403.                                 ;*** 20V8, 22V10, 20RA10 ***
  404. eve_1   moveq   #%00000010,d0           ; Q2 von IC1 auf HIGH
  405.  
  406. eve_2   or.l    d0,_outIC1
  407.         move.l  _outIC1,d0
  408.         bsr     @WriteByte
  409. ev_end  rts
  410.  
  411.  
  412.  
  413.  
  414.  
  415. * DisableVEdit:
  416. * remove edit voltage at pin 2 od pin 4
  417. * (pin depends on selected type of GAL)
  418. * call: DisableVEdit();
  419. @DisableVEdit:
  420.  
  421.         cmp.l   #HW_ELEKTOR_II,_hw_version
  422.         bne.s   dv_galer_hw
  423.                                 ;*** elektor hardware ***
  424.         move.l  _outIC4,d0
  425.         and.l   #%11011111,d0
  426.         moveq   #IC4,d1
  427.         bsr     @WriteByte              ; disable edit voltage (IC3a)
  428.         bra.s   dv_end
  429.  
  430.  
  431. dv_galer_hw:                    ;*** GALer hardware ***
  432.  
  433.         moveq   #IC1,d1                 ; IC1 einstellen
  434.         cmp.l   #GAL16V8,_GALType       ; 16V8 eingestellt?
  435.         bne.s   dve_1                   ; nein, dann wird 20V8 angenommen!
  436.                                 ;*** GAL16V8 ***
  437.         move.l  #%11111011,d0           ; Q3 von IC1 auf LOW
  438.         bra.s   dve_2
  439.                                 ;*** 20V8, 22V10, 20RA10 ***
  440. dve_1   move.l  #%11111101,d0           ; Q2 von IC1 auf low
  441.  
  442. dve_2   and.l   d0,_outIC1
  443.         move.l  _outIC1,d0
  444.         bsr     @WriteByte
  445. dv_end  rts
  446.  
  447.  
  448.  
  449.  
  450.  
  451. * LED:
  452. * switch LED on/off
  453. * ON:   LED on
  454. * OFF:  LED off 
  455. * call: LED(ON/OFF);
  456. @LED:
  457.         cmp.l   #HW_ELEKTOR_II,_hw_version
  458.         bne.s   led_galer_hw
  459.                                 ;*** elektor hardware ***
  460.         cmp.l   #ON,d0
  461.         bne.s   led_4
  462.         or.l    #%00000001,_outIC4
  463.         bra.s   led_3
  464. led_4   and.l   #%11111110,_outIC4
  465. led_3   move.l  _outIC4,d0
  466.         moveq   #IC4,d1
  467.         bsr     @WriteByte
  468.         bra.s   led_end
  469.  
  470.                                 ;*** GALer hardware ***
  471. led_galer_hw
  472.         cmp.l   #ON,d0
  473.         bne.s   led_2
  474.         or.l    #%01000000,_outIC1
  475.         bra.s   led_1
  476. led_2   and.l   #%10111111,_outIC1
  477. led_1   move.l  #IC1,d1
  478.         move.l  _outIC1,d0
  479.         bsr     @WriteByte              ; IC1 setzen
  480. led_end rts
  481.  
  482.  
  483.  
  484.  
  485.  
  486. * EnableVcc:
  487. * switch on voltage supply of GAL
  488. * GAL16V8: pin 22 of the textool socket
  489. * GAL20V8, 20RA10, 22V10: pin 24 of the textool socket
  490. * call: EnableVcc();
  491. @EnableVcc:
  492.  
  493.         movem.l d0-d7/a0-a6,-(sp)       ; Register retten
  494.         move.l  #300000,d0              ; 300 ms warten
  495.         jsr     @WaitForTimer
  496.         movem.l (sp)+,d0-d7/a0-a6
  497.  
  498.         cmp.l   #HW_ELEKTOR_II,_hw_version
  499.         bne.s   evc_galer_hw
  500.                                 ; *** elektor hardware ***
  501.         move.l  _outIC4,d0
  502.         cmp.l   #GAL16V8,_GALType       ; set voltage according to gal type
  503.         bne.s   evc_3
  504.         and.l   #%11101111,d0
  505.         bra.s   evc_4
  506. evc_3   or.l    #%00010000,d0
  507. evc_4   moveq   #IC4,d1
  508.         bsr     @WriteByte              ; seletct pin (22 or 24)
  509.  
  510.         move.l  _outIC4,d0
  511.         or.l    #%00000001,d0
  512.         moveq   #IC4,d1
  513.         bsr     @WriteByte              ; switch on voltage supply (IC3b)
  514.         bra.s   evc_end
  515.  
  516.  
  517. evc_galer_hw:                   ; *** GALer hardware ***
  518.  
  519.         move.l  #IC1,d1                 ; IC1 selektieren
  520.         cmp.l   #GAL16V8,_GALType       ; 16V8 eingestellt?
  521.         bne.s   evc_1                   ; nein, dann wird 20V8 angenommen!!!
  522.         moveq   #%00011000,d0           ; Q4,5 von IC1 auf HIGH=>+5V an Pin22
  523.         bra.s   evc_2
  524. evc_1   moveq   #%00010000,d0           ; Q5 auf HIGH => +5V an Pin 24  
  525. evc_2   or.l    d0,_outIC1
  526.         move.l  _outIC1,d0
  527.         bsr     @WriteByte              ; IC1 setzen
  528. evc_end rts
  529.  
  530.  
  531.  
  532.  
  533.  
  534. * DisableVcc:
  535. * switch off voltage supply of GAL
  536. * call: DisableVcc();
  537. @DisableVcc:
  538.         movem.l d0-d7/a0-a6,-(sp)       ; Register retten
  539.         move.l  #50000,d0               ; sicherheitshalber 50mS warten, bis
  540.         jsr     @WaitForTimer           ; das GAL die letzte Aktion richtig
  541.         movem.l (sp)+,d0-d7/a0-a6
  542.  
  543.         cmp.l   #HW_ELEKTOR_II,_hw_version
  544.         bne.s   dvc_galer_hw
  545.                                 ; *** elektor hardware ***
  546.         move.l  _outIC4,d0
  547.         and.l   #11111110,d0
  548.         moveq   #IC4,d1
  549.         bsr     @WriteByte
  550.         bra.s   dvc_end
  551.  
  552.  
  553. dvc_galer_hw                    ; *** GALer hardware ***
  554.  
  555.         move.l  #IC1,d1                 ; IC1 selektieren
  556.         cmp.l   #GAL16V8,_GALType       ; 16V8 eingestellt?
  557.         bne.s   dvc_1                   ; nein, dann wird 20V8 angenommen!!!
  558.         move.l  #%11100111,d0           ; Q4,5 von IC1 auf LOW
  559.         bra.s   dvc_2
  560. dvc_1   move.l  #%11101111,d0           ; Q5 auf HIGH
  561. dvc_2   and.l   d0,_outIC1
  562.         move.l  _outIC1,d0
  563.         bsr     @WriteByte              ; IC1 setzen
  564. dvc_end rts
  565.  
  566.  
  567.  
  568.  
  569.  
  570. * EnableOutput:
  571. * switch Output-Enable inputs (OE) of IC3, IC4, IC5 HIGH
  572. * elektor hardware does not support this, so skip it
  573. * call: EnableOutput();
  574. @EnableOutput:
  575.         cmp.l   #HW_ELEKTOR_II,_hw_version
  576.         beq.s   eo_end
  577.  
  578.         move.l  #IC1,d1
  579.         or.l    #%00100000,_outIC1
  580.         move.l  _outIC1,d0
  581.         bsr     @WriteByte
  582. eo_end  rts
  583.  
  584.  
  585.  
  586.  
  587.  
  588. * DisableOutput:
  589. * switch Output-Enable inputs (OE) of IC3, IC4, IC5 HIGH
  590. * elektor hardware does not support this, so skip it
  591. * call: EnableOutput();
  592. @DisableOutput:
  593.         cmp.l   #HW_ELEKTOR_II,_hw_version
  594.         beq.s   do_end
  595.  
  596.         move.l  #IC1,d1
  597.         and.l   #%11011111,_outIC1
  598.         move.l  _outIC1,d0
  599.         bsr     @WriteByte
  600. do_end  rts
  601.  
  602.  
  603.  
  604.  
  605.  
  606. * ReadByte:
  607. * read bit from IC6a, IC6c or byte from IC7
  608. * call:   byte=ReadByte(source);
  609. *         source: IC6a, IC6b, IC7
  610. * PD3 is already HIGH, so reading is possible
  611. * elektor's hardware does not support the testing of GALs, so skip it
  612. @ReadByte:
  613.         cmp.l   #HW_ELEKTOR_II,_hw_version
  614.         beq     rb_end
  615.  
  616.  
  617.         and.b   #%11111100,ciaaprb      ; set PD0 and PD1 LOW
  618.  
  619.         cmp.l   #HW_GALER_1_3,_hw_version
  620.         beq     rb_version1_3           ; hardware version 1.3
  621.  
  622. ; *** this is for the hardware versions 1.0, 1.1, 1.2 ***
  623.  
  624.         cmp.l   #IC6a,d0                ; read from IC6a?
  625.         bne.s   rb_IC7                  ; no, then IC7
  626.         or.b    #%00000001,ciaaprb      ; PD0 HIGH=>HIGH at Clk of IC7
  627.                                         ; set PD0 HIGH =>IC6a is selected
  628.  
  629.         bsr     @PollDelay
  630.  
  631.         moveq   #0,d0
  632.         move.b  ciabpra,d0
  633.         not.b   d0                      ; invert
  634.         and.b   #%00000001,d0           ; get BUSY bit
  635.         bra     rb_end                  ; now we have the state of pin 22
  636. rb_IC7
  637.         moveq   #0,d0                   ; PD3 is HIGH=>reading is possible
  638.  
  639.         or.b    #%00000100,ciaaprb      ; set PD2 (Strobe) HIGH => put data
  640.         and.b   #%11111011,ciaaprb      ; from input register into shift register
  641.                                         ; then set PD2 LOW again
  642.                                         ; PD3 is HIGH => reading is possible
  643.         move.l  d2,-(sp)
  644.         moveq   #7,d2                   ; loop counter
  645. rb_l1   rol.b   #1,d0
  646.  
  647.         bsr     @PollDelay
  648.  
  649.         move.b  ciabpra,d1              ; get BUSY bit
  650.         and.b   #%00000001,d1           ; AND BUSY bit
  651.         or.b    d1,d0                   ; move BUSY bit in D0
  652.         and.b   #%11111100,ciaaprb      ; set PD0 LOW => LOW at Clk of IC7
  653.         or.b    #%00000001,ciaaprb      ; set PD0 HIGH => HIGH at Clk of IC7
  654.                                         ; ==> next bit is available
  655.         nop
  656.         nop
  657.         and.b   #%11111100,ciaaprb      ; set PD0 LOW=>IC6b is selected
  658.         dbf     d2,rb_l1                ; read 8 bits
  659.         not.b   d0                      ; invert them
  660.         move.l  (sp)+,d2
  661.         bra     rb_end
  662.  
  663.  
  664. ; *** this is for hardware version 1.3  ***
  665.  
  666. rb_version1_3:
  667.  
  668.         cmp.l   #IC6a,d0                ; read from IC6a?
  669.         bne.s   rb_c1
  670.                                         ; read IC6a
  671.                                         ; PD0 and PD1 is LOW=>IC6a is selected
  672.         bsr     @PollDelay
  673.  
  674.         moveq   #0,d0
  675.         move.b  ciabpra,d0              ; read parallel port
  676.         not.b   d0                      ; invert
  677.         and.b   #%00000001,d0           ; get BUSY bit
  678.         bra.s   rb_end                  ; now we have the state of pin 22
  679.  
  680.  
  681. rb_c1   cmp.l   #IC6c,d0                ; read from IC6b?
  682.         bne.s   rb_c2                   ; no, then IC7
  683.                                         ; Read IC6c
  684.  
  685.         or.b    #%00000010,ciaaprb      ; PD0 LOW, PD1 HIGH => IC6c is selected
  686.         moveq   #0,d0
  687.  
  688.         bsr     @PollDelay
  689.  
  690.         move.b  ciabpra,d0              ; read parallel port
  691.         not.b   d0                      ; invert
  692.         and.b   #%00000001,d0           ; get BUSY bit
  693.         bra.s   rb_end                  ; now we have the state of pin 23
  694.  
  695.  
  696. rb_c2                                   ; read IC7
  697.         moveq   #0,d0                   ; PD3 is HIGH=>reading is possible
  698.  
  699.         or.b    #%00000101,ciaaprb      ; set PD2 (Strobe) HIGH => put data
  700.         and.b   #%11111011,ciaaprb      ; from input register into shift register
  701.                                         ; then set PD2 LOW again
  702.                                         ; PD3 is HIGH => reading is possible
  703.  
  704.         move.l  d2,-(sp)
  705.         moveq   #7,d2                   ; loop counter
  706. rb_l2   rol.b   #1,d0
  707.  
  708.         bsr     @PollDelay
  709.  
  710.         move.b  ciabpra,d1              ; get BUSY bit
  711.         and.b   #%00000001,d1           ; AND BUSY bit
  712.         or.b    d1,d0                   ; move BUSY bit in D0
  713.         and.b   #%11111100,ciaaprb      ; set PD0 LOW => LOW at Clk of IC7
  714.         or.b    #%00000001,ciaaprb      ; set PD0 HIGH => HIGH at Clk of IC7
  715.                                         ; ==> next bit is available
  716.         dbf     d2,rb_l2                ; read 8 bits
  717.  
  718.         not.b   d0                      ; invert them
  719.         move.l  (sp)+,d2
  720.  
  721. rb_end
  722.         rts                             ; D0 is result
  723.  
  724.  
  725.  
  726.  
  727.  
  728. * SetRow:
  729. * set address to RAG0-RAG5
  730. * call: SetRow(row);
  731. * row:    row which should be selected (0-63)
  732. @SetRow:
  733.  
  734.         move.l  d0,-(sp)                ; Row (D0) auf Stack
  735.  
  736.  
  737.         cmp.l   #GAL22V10,_GALType
  738.         beq     setrow22V10
  739.         cmp.l   #GAL20RA10,_GALType
  740.         beq     setrow20RA10
  741.  
  742.  
  743.  
  744.         cmp.l   #HW_ELEKTOR_II,_hw_version
  745.         bne     sr_galer_hw
  746.  
  747.                         ; *** elektor hardware ***
  748.                                         ; RAG4 and RAG5 are equal for both,
  749.                                         ; GAL16V8 and GAL20V8
  750.         and.l   #%10111110,_outIC1      ; clear RAG4 and RAG5
  751.         and.l   #%00100000,d0
  752.         asl.b   #1,d0                   ; get RAG5
  753.         or.l    d0,_outIC1              ; set RAG5
  754.         move.l  (sp),d0
  755.         and.l   #%00010000,d0
  756.         asr.b   #4,d0                   ; get RAG4
  757.         or.l    d0,_outIC1              ; set RAG4
  758.  
  759.         cmp.l   #GAL16V8,_GALType
  760.         bne.s   sr_20V8
  761.  
  762.                         ; *** GAL16V8 ***
  763.         move.l  (sp),d0
  764.         and.l   #%00000001,d0           ; get RAG0
  765.         asl.b   #2,d0
  766.         and.l   #%11111011,_outIC1
  767.         or.l    d0,_outIC1              ; set RAG0
  768.  
  769.         move.l  (sp),d0
  770.         and.l   #%00000110,d0           ; get RAG1 and RAG2
  771.         and.l   #%11111001,_outIC4
  772.         or.l    d0,_outIC4              ; set RAG1 and RAG2
  773.  
  774.         move.l  (sp),d0
  775.         and.l   #%00001000,d0           ; get RAG3
  776.         asl.b   #2,d0
  777.         and.l   #%11011111,_outIC1
  778.         or.l    d0,_outIC1              ; set RAG3
  779.  
  780.         bra.s   sr_write
  781.  
  782. sr_20V8                 ; *** GAL20V8 ***
  783.         move.l  (sp),d0
  784.         and.l   #%00000001,d0           ; get RAG0
  785.         asl.b   #4,d0
  786.         and.l   #%11101111,_outIC1
  787.         or.l    d0,_outIC1              ; set RAG0
  788.  
  789.         move.l  (sp),d0
  790.         and.l   #%00000110,d0           ; get RAG1 and RAG2
  791.         asl.b   #5,d0
  792.         and.l   #%00111111,_outIC4
  793.         or.l    d0,_outIC4              ; set RAG1 and RAG2
  794.  
  795.         move.l  (sp),d0
  796.         and.l   #%00001000,d0           ; get RAG3
  797.         asr.b   #2,d0
  798.         and.l   #%11111101,_outIC4
  799.         or.l    d0,_outIC4              ; set RAG3
  800.  
  801. sr_write                                ; write bytes to ICs
  802.         move.l  #IC1,d1
  803.         move.l  _outIC1,d0
  804.         bsr     @WriteByte
  805.  
  806.         bra     setrowend
  807.  
  808.  
  809.  
  810. sr_galer_hw             ; *** GALer hardware ***
  811.  
  812.                         ; ***  GAL16V8 und GAL20V8  ***
  813.                                     ; RAG5 setzen (bei 16 und 20V8 gleich)
  814.         and.l   #$fe,_outIC5            ; Bit0(=RAG5) löschen
  815.         asr.b   #5,d0                   ; Bit0 von D0=RAG5
  816.         or.l    d0,_outIC5              ; RAG5=Bit von D0=> RAG5 gesetzt
  817.  
  818.         cmp.l   #GAL16V8,_GALType       ; GAL16V8?
  819.         bne.s   setrow20V8              ; nein, dann GAL20V8 annehmen
  820.  
  821.                                 ;*** GAL16V8 ***
  822.                                     ; RAG0 setzen
  823.         move.l  (sp),d0                 ; row holen
  824.         and.l   #$ef,_outIC3            ; Bit4(=RAG0) löschen
  825.         and.l   #1,d0                   ; Bit0 von "row" ausmaskieren
  826.         asl.b   #4,d0
  827.         or.l    d0,_outIC3              ; Bit4(=RAG0) setzen
  828.                                     ; RAG1-RAG4 setzen
  829.         move.l  (sp),d0                 ; row holen
  830.         and.l   #$0f,_outIC4            ; Bit4-7(=RAG1-RAG4) löschen
  831.         and.l   #%00011110,d0           ; Bit1-4 von "row" ausmaskieren
  832.         asl.l   #3,d0                   ; an Bit4-7 schieben
  833.         or.l    d0,_outIC4              ; RAG1-RAG4 setzen
  834.         bra.s   write
  835.                                 ;*** GAL20V8 ***
  836. setrow20V8                          ; RAG0 für GAL20V8 setzen
  837.         move.l  (sp),d0                 ; row holen
  838.         and.l   #%11011111,_outIC3      ; Bit5(=RAG0) löschen
  839.         and.l   #1,d0                   ; Bit0 von "row" ausmaskieren
  840.         asl.b   #5,d0
  841.         or.l    d0,_outIC3              ; Bit5(=RAG0) setzen
  842.                                     ; RAG4 setzen
  843.         move.l  (sp),d0                 ; row holen
  844.         and.l   #%01111111,_outIC4      ; Bit7(=RAG4) löschen
  845.         and.l   #%00010000,d0           ; Bit4 von "row" ausmaskieren
  846.         asl.l   #3,d0
  847.         or.l    d0,_outIC4              ; Bit7(=RAG4) setzen
  848.                                     ; RAG1-RAG3 setzen
  849.         move.l  (sp),d0                 ; row holen
  850.         and.l   #%11100011,_outIC4      ; Bit2-4(=RAG1-RAG3) löschen
  851.         and.l   #%00001110,d0           ; Bit1-3 aus "row" ausmaskieren
  852.         asl.l   #1,d0
  853.         or.l    d0,_outIC4              ; RAG1-RAG3 setzen
  854.  
  855. write                               ; errechnete Werte in ICs schreiben
  856.         move.l  #IC3,d1
  857.         move.l  _outIC3,d0
  858.         bsr     @WriteByte
  859.  
  860.         move.l  #IC4,d1
  861.         move.l  _outIC4,d0
  862.         bsr     @WriteByte
  863.  
  864.         move.l  #IC5,d1
  865.         move.l  _outIC5,d0
  866.         bsr     @WriteByte
  867.  
  868.         bra.s   setrowend
  869.  
  870.                         ; ***  GAL22V10 und GAL20RA10  ***
  871. setrow22V10                     ; bei 22V10 und 20RA10 GALs wird RAG0-5 in
  872. setrow20RA10                    ; das interne Schiebereg. des GALs getaktet,
  873.                                 ; da diese GALs keine RAG-Pins haben
  874.         moveq   #5,d1                   ; D0 = Row
  875. setrow1
  876.         movem.l d0/d1,-(sp)
  877.         and.l   #%0000001,d0            ; LSB ausmaskieren
  878.         bsr.s   @SDIn                   ; RAGx ins Schieberegister des
  879.         bsr     @Clock                  ; GALs takten
  880.         movem.l (sp)+,d0/d1
  881.         asr.b   #1,d0
  882.         dbf     d1,setrow1
  883.  
  884. setrowend
  885.         addq.l  #4,sp                   ; Stack korrigieren
  886.         rts
  887.  
  888.  
  889.  
  890.  
  891.  
  892. * SDIn:
  893. * set bit at SDIn input of the GAL (pin 11 of the textool socket)
  894. * call: SDIn(bit);    bit: 0=LOW; 1=HIGH
  895. @SDIn:
  896.  
  897.         cmp.l   #HW_ELEKTOR_II,_hw_version
  898.         bne.s   sd_galer_hw
  899.                                 ; *** elektor hardware ***
  900.         asl.b   #7,d0                   ; shift bit #0 to bit #7
  901.         and.l   #%01111111,_outIC1      ; clear bit #7 of IC1
  902.         or.l    d0,_outIC1
  903.         move.l  _outIC1,d0
  904.         move.l  #IC1,d1
  905.         bsr     @WriteByte              ; set SDIn
  906.         bra.s   sd_end
  907.  
  908. sd_galer_hw                     ; *** GALer hardware ***
  909.                                         ; Bit steht in d0
  910.         asl.b   #2,d0                   ; an die richtige Stelle schieben
  911.         and.l   #%11111011,_outIC5      ; SDIn-Bit löschen
  912.         or.l    d0,_outIC5              ; Bit auf LOW oder HIGH setzen
  913.         move.l  #IC5,d1
  914.         move.l  _outIC5,d0
  915.         bsr     @WriteByte
  916. sd_end  rts
  917.  
  918.  
  919.  
  920.  
  921.  
  922. * SDOut:
  923. * read bit from SDOut (SDOut is an open drain output!) 
  924. * pin 14 (GAL16V8, 22V10, 20RA10), pin 15 (GAL20V8) of the textool socket
  925. * call: bit=SDOut();
  926. * bit: 0: SDOut=LOW; 1: SDOut=HIGH
  927. @SDOut:
  928.         cmp.l   #HW_ELEKTOR_II,_hw_version
  929.         bne.s   sdo_galer_hw
  930.                                 ; *** elektor hardware  ***
  931.         cmp.l   #GAL20V8,_GALType
  932.         beq.s   sdo_c1
  933.         move.l  _outIC2,d0
  934.         and.b   #%11101111,d0           ; select IC2a
  935.         move.l  #IC2,d1
  936.         bsr     @WriteByte
  937.         nop                             ; nops are not really necessary
  938.         nop
  939.         nop
  940.         move.b  ciabpra,d0              ; get BUSY bit
  941.         and.l   #%00000001,d0
  942.         bra.s   sdo_end
  943. sdo_c1                              ; GAL20V8
  944.         move.l  _outIC2,d0
  945.         or.b    #%00010000,d0           ; select IC2b
  946.         move.l  #IC2,d1
  947.         bsr     @WriteByte
  948.         nop                             ; nops are not really necessary
  949.         nop
  950.         nop
  951.         move.b  ciabpra,d0              ; get BUSY bit
  952.         and.l   #%00000001,d0
  953.         bra.s   sdo_end
  954.  
  955.  
  956. sdo_galer_hw                    ; *** GALer hardware ***
  957.         move.l  #IC7,d0                 ; ein Byte aus IC7 holen
  958.         bsr     @ReadByte               ; Bit0=Pin14, Bit1=Pin15
  959.  
  960.         cmp.l   #GAL20V8,_GALType       ; GAL20V8 eingestellt?
  961.         beq.s   sdo_c2                  ; nein, dann 16V8, 22V10, 20RA10
  962.         and.l   #1,d0                   ; Bit0 ausmaskieren
  963.         bra.s   sdo_end                 ; D0=Bit
  964.                                     ; GAL20V8
  965. sdo_c2  asr.l   #1,d0                   ; SDOut-Bit an Bit-Pos. 0
  966.         and.l   #1,d0
  967. sdo_end                                 ; 32-Bit-Ergebnis in D0
  968.         rts
  969.  
  970.  
  971.  
  972.  
  973.  
  974. * PollDelay
  975. * wait about 10us
  976. * This function does polling. I know that this is not a very good methode in
  977. * a multitasking system. But we have to wait just some micro seconds.
  978. * This is not possible when using the timer device or CIA timer interrupts.
  979. * Using this things lasts at least 400us (timer device) or 180us (CIA timer
  980. * interrupts). This is too long. So we have to poll, sorry.
  981. *
  982. * A0 will be changed!
  983. @PollDelay:
  984.  
  985.         move.l  _cia_timer_low,a0       ; load timer
  986.         move.b  #255,(a0)
  987.         move.l  _cia_timer_high,a0
  988.         clr.b  (a0)
  989.                                         ; start timer
  990.         move.l  _cia_timer_cr,a0
  991.         move.b  _cia_timer_start,(a0)
  992.  
  993.         move.l  _cia_timer_low,a0
  994. PD_loop:
  995.         cmp.b   #250,(a0)               ; poll timer's low byte
  996.         bhi.s   PD_loop
  997.  
  998.                                         ; stop timer
  999.         move.l  _cia_timer_cr,a0
  1000.         move.b  _cia_timer_stop,(a0)
  1001.  
  1002.         rts
  1003.  
  1004.  
  1005.  
  1006.  
  1007.  
  1008.  
  1009.  
  1010. * Clock:
  1011. * generate Low-High-Low transition at GAL's clock input (pin 10 of the
  1012. * textool socket) - when calling this function SCLK must be Low already
  1013. *
  1014. * call: Clock();
  1015. @Clock:
  1016.         cmp.l   #HW_ELEKTOR_II,_hw_version
  1017.         bne.s   cl_galer_hw
  1018.                                 ; *** elektor hardwar ***
  1019.         or.l    #%00000010,_outIC1      ; SCLK HIGH
  1020.         move.l  #IC1,d1
  1021.         move.l  _outIC1,d0
  1022.         bsr     @WriteByte
  1023.  
  1024.         and.l   #%111111101,_outIC1     ; SCLK LOW
  1025.         move.l  #IC1,d1
  1026.         move.l  _outIC1,d0
  1027.         bsr     @WriteByte
  1028.         bra.s   cl_end
  1029.         
  1030. cl_galer_hw                     ; *** GALer hardware ***
  1031.         or.l    #%00000010,_outIC5      ; SCLK-Bit auf HIGH
  1032.         move.l  #IC5,d1
  1033.         move.l  _outIC5,d0
  1034.         bsr     @WriteByte
  1035.  
  1036.         and.l   #%11111101,_outIC5      ; SCLK-Bit auf LOW
  1037.         move.l  #IC5,d1
  1038.         move.l  _outIC5,d0
  1039.         bsr     @WriteByte
  1040.  
  1041. cl_end  rts
  1042.  
  1043.  
  1044.  
  1045.  
  1046.  
  1047. * STRImpuls:
  1048. * set /STR low (pin 13 of the textool socket) for a duration of "STRLength"
  1049. * call: STRImpuls(long STRLength);
  1050. * STRLength: duration of the low impulse in microsecondes (32 bit!)
  1051. @STRImpuls:
  1052.         movem.l d0-d7/a0-a6,-(sp)       ; Register retten
  1053.  
  1054.         move.l  4,a6
  1055.         jsr     _LVOForbid(a6)          ; forbid task switching
  1056.  
  1057.         cmp.l   #HW_ELEKTOR_II,_hw_version
  1058.         bne.s   sim_galer_hw
  1059.                                 ; *** elektor hardware **
  1060.         and.l   #%11110111,_outIC1      ; set STR LOW
  1061.         move.l  #IC1,d1
  1062.         move.l  _outIC1,d0
  1063.         bsr     @WriteByte
  1064.  
  1065.         cmp.l   #300,(sp)               ; writing a value into the IC needs
  1066.         bls.s   sim_c1                  ; about 300us, so it makes no sense
  1067.         move.l  (sp),d0                 ; to use the timer if the time to
  1068.         sub.l   #300,d0                 ; wait is less than 300us
  1069.         jsr     @WaitForTimer
  1070. sim_c1
  1071.         or.l    #%00001000,_outIC1      ; set STR HIGH
  1072.         move.l  #IC1,d1
  1073.         move.l  _outIC1,d0
  1074.         bsr     @WriteByte
  1075.         bra.s   sim_end
  1076.  
  1077.  
  1078. sim_galer_hw                    ; *** GALer hardware ***
  1079.         and.l   #%11110111,_outIC5      ; STR-Pin auf LOW
  1080.         move.l  #IC5,d1
  1081.         move.l  _outIC5,d0
  1082.         bsr     @WriteByte
  1083.  
  1084.         cmp.l   #100,(sp)               ; bis ein Wert in ein IC getaktet wird
  1085.         bls.s   sim_c2                  ; vergehen ca. 100us => keinen Timer
  1086.         move.l  (sp),d0                 ; Dauer des Impulses in Mikrosekunden
  1087.         jsr     @WaitForTimer           ; Low-Impuls
  1088. sim_c2
  1089.         or.l    #%00001000,_outIC5      ; STR-Pin wieder auf HIGH
  1090.         move.l  #IC5,d1
  1091.         move.l  _outIC5,d0
  1092.         bsr     @WriteByte
  1093.  
  1094. sim_end jsr     _LVOPermit(a6)          ; permit task switching
  1095.  
  1096.         movem.l (sp)+,d0-d7/a0-a6       ; Registerinhalte zurückholen
  1097.         rts
  1098.  
  1099.  
  1100.  
  1101.  
  1102.  
  1103. * SetPV:
  1104. * set P/V pin 
  1105. * call:  SetPV(mode);
  1106. * mode :   VERIFY (read, P/V low), PROG (write, P/V high)
  1107. @SetPV:
  1108.                                         ; mode = D0
  1109.  
  1110.         cmp.l   #HW_ELEKTOR_II,_hw_version
  1111.         bne.s   spv_galer_hw
  1112.                                 ; *** elektor hardware ***
  1113.  
  1114.         cmp.l   #GAL16V8,_GALType
  1115.         bne.s   spv_c1
  1116.                                     ; *** GAL16V8 ***
  1117.         move.l  _outIC1,d1
  1118.         and.l   #%11101111,d1           ; clear P/V
  1119.         asl.b   #4,d0
  1120.         or.l    d0,d1                   ; set P/V according to mode
  1121.         move.l  d1,d0
  1122.         move.l  #IC1,d1
  1123.         bsr     @WriteByte
  1124.         bra     spv_end
  1125.  
  1126. spv_c1
  1127.         cmp.l   #GAL20V8,_GALType
  1128.         bne.s   spv_c2              ; *** GAL20V8 ***
  1129.  
  1130.         move.l  _outIC4,d1
  1131.         and.l   #%11110111,d1           ; clear P/V
  1132.         asl.b   #3,d0
  1133.         or.l    d0,d1                   ; set P/V according to mode
  1134.         move.l  d1,d0
  1135.         move.l  #IC4,d1
  1136.         bsr     @WriteByte
  1137.         bra.s   spv_end
  1138.  
  1139. spv_c2                              ;*** 22V10, 20RA10 ***
  1140.         move.l  _outIC4,d1
  1141.         and.l   #%10111111,d1           ; clear P/V
  1142.         asl.b   #6,d0
  1143.         or.l    d0,d1                   ; set P/V according to mode
  1144.         move.l  d1,d0
  1145.         move.l  #IC4,d1
  1146.         bsr     @WriteByte
  1147.         bra.s   spv_end
  1148.  
  1149.  
  1150.  
  1151. spv_galer_hw                    ; *** GALer hardware ***
  1152.  
  1153.         cmp.l   #GAL16V8,_GALType       ; GAL16V8?
  1154.         bne.s   spv_c3                  ; nein, dann 1
  1155.  
  1156.                                 ;***  GAL16V8  ***
  1157.         move.l  _outIC3,d1
  1158.         and.l   #%11011111,d1
  1159.         asl.b   #5,d0                   ; Mode-Bit zu Bit 5 schieben
  1160.         or.l    d0,d1
  1161.         move.l  d1,d0                   ; P/V setzen
  1162.         move.l  #IC3,d1                 ; IC3 setzen
  1163.         bsr     @WriteByte
  1164.         bra.s   spv_end
  1165.  
  1166. spv_c3
  1167.         cmp.l   #GAL20V8,_GALType
  1168.         bne.s   spv_c4
  1169.                                 ;***  GAL20V8  ***
  1170.  
  1171.         move.l  _outIC3,d1
  1172.         and.l   #%10111111,d1
  1173.         asl.b   #6,d0                   ; Mode-Bit zu Bit 6 schieben
  1174.         or.l    d0,d1
  1175.         move.l  d1,d0                   ; P,/V-Bit setzen
  1176.         move.l  #IC3,d1                 ; IC3 setzen
  1177.         bsr     @WriteByte
  1178.         bra.s   spv_end
  1179.  
  1180. spv_c4
  1181.                                 ;***  22V10, 20RA10  ***
  1182.  
  1183.         move.l  _outIC4,d1
  1184.         and.l   #%11111011,d1
  1185.         asl.b   #2,d0
  1186.         or.l    d0,d1
  1187.         move.l  d1,d0                   ; P,/V-Bit setzen
  1188.         move.l  #IC4,d1                 ; IC4 setzen
  1189.         bsr     @WriteByte
  1190.  
  1191. spv_end
  1192.         rts
  1193.  
  1194.  
  1195.  
  1196.  
  1197.  
  1198.  
  1199. * Edit-Mode:
  1200. * switch GAL into edit mode: /STR = HIGH, P/V = LOW,
  1201. * SDOUT(open drain output!) = VIH, all VIL-pins = VIL
  1202. * call: EditMode(mode);
  1203. * mode: PROG or VERIFY (needed to select voltage)
  1204. @EditMode:
  1205.         movem.l d0-d7/a0-a6,-(sp)       ; Register sichern
  1206.  
  1207.  
  1208.         cmp.l   #HW_ELEKTOR_II,_hw_version
  1209.         bne.s   em_galer_hw
  1210.                                 ; *** elektor hardware ***
  1211.         cmp.l   #GAL16V8,_GALType       ; GAL16V8
  1212.         bne.s   em_c7                   ; no, then goto em_c7
  1213.                                     ;*** GAL16V8 ***
  1214.         moveq   #IC4,d1
  1215.         moveq   #%00001000,d0
  1216.         bsr     @WriteByte
  1217.  
  1218.         moveq   #IC1,d1
  1219.         moveq   #%00001000,d0           ; set /STR high
  1220.         bsr     @WriteByte
  1221.  
  1222.         moveq   #IC2,d1
  1223.         moveq   #%00000000,d0           ; set SDOut high and
  1224.         bsr     @WriteByte
  1225.         bra     em_c2                   ; select voltage
  1226.  
  1227. em_c7   cmp.l   #GAL20V8,_GALType
  1228.         bne.s   em_c8               ;*** GAL20V8 ***
  1229.  
  1230.         moveq   #IC4,d1
  1231.         moveq   #%00000000,d0
  1232.         bsr     @WriteByte
  1233.  
  1234.         moveq   #IC1,d1
  1235.         moveq   #%00001000,d0           ; set /STR high
  1236.         bsr     @WriteByte
  1237.  
  1238.         moveq   #IC2,d1
  1239.         moveq   #%00010000,d0           ; set SDOut high and
  1240.         bsr     @WriteByte
  1241.         bra.s   em_c2                   ; select voltage
  1242.  
  1243. em_c8                           ;*** GAL20RA10 ***
  1244.                                 ;*** GAL22V10  ***
  1245.         moveq   #IC4,d1
  1246.         moveq   #%00000000,d0
  1247.         bsr     @WriteByte
  1248.  
  1249.         moveq   #IC1,d1
  1250.         moveq   #%00001000,d0           ; set /STR high
  1251.         bsr     @WriteByte
  1252.  
  1253.         moveq   #IC2,d1
  1254.         moveq   #%00000000,d0           ; set SDOut high and
  1255.         bsr     @WriteByte
  1256.         bra.s   em_c2                   ; select voltage
  1257.  
  1258.  
  1259.  
  1260. em_galer_hw                     ; *** GALer hardware ***
  1261.         cmp.l   #GAL16V8,_GALType       ; GAL16V8?
  1262.         bne.s   em_c1                   ; nein, dann em_c1
  1263.  
  1264.                                 ;*** GAL16V8 ***
  1265.         moveq   #IC3,d1                 ; IC3, P/V auf LOW
  1266.         moveq   #%00000000,d0
  1267.         bsr     @WriteByte
  1268.  
  1269.         moveq   #IC4,d1
  1270.         moveq   #%00000000,d0           ; IC4 initialisieren
  1271.         bsr     @WriteByte
  1272.  
  1273.         moveq   #IC5,d1                 ; /STR auf HIGH
  1274.         moveq   #%00011000,d0           ; IC5 initialisieren
  1275.         bsr     @WriteByte
  1276.         bra.s   em_c2
  1277.  
  1278.  
  1279. em_c1   cmp.l   #GAL20V8,_GALType
  1280.         bne.s   em_c5
  1281.  
  1282.                                 ;*** GAL20V8 ***
  1283.         moveq   #IC3,d1                 ; IC3, P/V auf LOW
  1284.         moveq   #%00000000,d0
  1285.         bsr     @WriteByte
  1286.  
  1287.         moveq   #IC4,d1
  1288.         moveq   #%00000000,d0           ; IC4 initialisieren
  1289.         bsr     @WriteByte
  1290.  
  1291.         moveq   #IC5,d1                 ; /STR auf HIGH
  1292.         moveq   #%00101000,d0           ; IC5 initialisieren
  1293.         bsr     @WriteByte
  1294.         bra.s   em_c2
  1295.  
  1296.  
  1297. em_c5
  1298.                                 ;*** GAL20RA10 ***
  1299.                                 ;*** GAL22V10  ***
  1300.  
  1301.         moveq   #IC3,d1                 ; IC3, OPs auf VIL
  1302.         moveq   #%00000000,d0
  1303.         bsr     @WriteByte
  1304.  
  1305.         moveq   #IC4,d1
  1306.         moveq   #%00000000,d0           ; IC4, P/V auf LOW
  1307.         bsr     @WriteByte
  1308.  
  1309.         moveq   #IC5,d1                 ; /STR, SDOUT auf HIGH
  1310.         moveq   #%00011000,d0           ; IC5 initialisieren
  1311.         bsr     @WriteByte
  1312.  
  1313.  
  1314. em_c2
  1315.                                     ; richtige Spannung auswählen
  1316.         cmp.l   #VERIFY,(sp)            ; Lesen?
  1317.         bne.s   em_c3                   ; nein, dann Programmieren!
  1318.  
  1319.         moveq   #4,d0                   ; 12 Volt einstellen
  1320.         cmp.l   #GAL22V10,_GALType      ; wenn 22V10, dann 16.5 Volt
  1321.         bne.s   em_c6
  1322.         moveq   #0,d0
  1323. em_c6   bsr     @SetVolt
  1324.         bra.s   em_c4
  1325.  
  1326. em_c3   move.l  _prog_volt,d0           ; Programmierspannung einstellen
  1327.         bsr     @SetVolt
  1328.  
  1329. em_c4   bsr     @VeditOn                ; Edit-Spannung aufbauen
  1330.  
  1331.         move.l  #50000,d0               ; 50 ms warten, bis sich die
  1332.         jsr     @WaitForTimer           ; Edit-Spannung aufgebaut hat
  1333.  
  1334.         bsr     @EnableOutput           ; Bits anlegen
  1335.         bsr     @EnableVcc              ; Vcc anlegen
  1336.  
  1337.         move.l  #100000,d0              ; Prellzeit der Relais überbrücken
  1338.         jsr     @WaitForTimer
  1339.  
  1340.         bsr     @EnableVEdit            ; Edit-Spannung anlegen
  1341.                                     ; GAL befindet sich jetzt im Edit-Mode
  1342.         moveq   #5,d0                   ; 5 us warten bevor nächste Aktion
  1343.         jsr     @WaitForTimer           ; erlaubt ist
  1344.  
  1345.         movem.l (sp)+,d0-d7/a0-a6       ; Registerinhalte zurückholen
  1346.         rts
  1347.  
  1348.  
  1349.  
  1350.  
  1351.  
  1352. * ExitEditMode:
  1353. * Schaltet zuerst VEdit und VCC ab, dann wird der Inhalt der ICs
  1354. * zurückgesetzt.
  1355. * Aufruf: ExitEditMode();
  1356. @ExitEditMode:
  1357.         movem.l d0-d7/a0-a6,-(sp)       ; Register sichern
  1358.  
  1359.         bsr     @DisableVEdit
  1360.  
  1361.         bsr     @DisableVcc
  1362.  
  1363.         bsr     @InitHardware
  1364.  
  1365.         bsr     @EnableOutput
  1366.  
  1367.         movem.l (sp)+,d0-d7/a0-a6
  1368.         rts
  1369.  
  1370.  
  1371.  
  1372.  
  1373.  
  1374. * SetVolt:
  1375. * set voltage
  1376. * GALer:   select voltage by use of IC 10 and IC 11
  1377. * elektor: set bits of AD converter
  1378. * call:   SetVolt(value);
  1379. * value:  0=16.50 Volt; 1=15.75 Volt; 2=14.5 Volt; 3=14.00 Volt; 4=12.00 Volt
  1380. *
  1381. @SetVolt:
  1382.                                         ; Parameter in D0
  1383.         move.l  d0,-(sp)                ; Wert sichern
  1384.  
  1385.         cmp.l   #HW_ELEKTOR_II,_hw_version
  1386.         bne.s   sv_galer_hw
  1387.                                 ; *** elektor hardware ***
  1388.  
  1389.         move.l  _outIC2,d1              ; clear all bits of IC 2 which
  1390.         and.l   #%00110000,d1           ; belongs to the DA converter
  1391.  
  1392.         tst     d0                      ; 16.5 V
  1393.         bne.s   sv_c1 
  1394.         or.l    #%01000100,d1
  1395.         bra.s   sv_c5
  1396.  
  1397. sv_c1   cmp     #1,d0                   ; 15.75 V
  1398.         bne.s   sv_c2
  1399.         or.l    #%10001111,d1
  1400.         bra.s   sv_c5
  1401.  
  1402. sv_c2   cmp     #2,d0                   ; 14.5 V
  1403.         bne.s   sv_c3
  1404.         or.l    #%10000101,d1
  1405.         bra.s   sv_c5
  1406.  
  1407. sv_c3   cmp     #3,d0                   ; 14.0 V
  1408.         bne.s   sv_c4
  1409.         or.l    #%10000001,d1
  1410.         bra.s   sv_c5
  1411.  
  1412. sv_c4                                   ; 12.0 V
  1413.         or.l    #%10000000,d1
  1414.  
  1415.  
  1416. sv_c5   move.l  d1,d0                   ; write value into d0
  1417.         moveq   #IC2,d1                 ; write IC number into d1
  1418.         bsr     @WriteByte              ; set voltage
  1419.         bra.s   sv_end
  1420.  
  1421.  
  1422.  
  1423. sv_galer_hw                     ; *** GALer hardware ***
  1424.  
  1425.         and.l   #%00000001,d0
  1426.         rol.l   #7,d0
  1427.         and.l   #%01111111,_outIC1
  1428.         or.l    d0,_outIC1              ; Q8 (Pin 11) von IC1 setzen
  1429.         move.l  _outIC1,d0
  1430.         move.l  #IC1,d1
  1431.         bsr     @WriteByte
  1432.  
  1433.         move.l  (sp),d0
  1434.         and.l   #%00000110,d0
  1435.         rol.l   #5,d0
  1436.         and.l   #%00111111,_outIC5
  1437.         or.l    d0,_outIC5              ; Q7 und Q8 von IC5 setzen
  1438.         move.l  _outIC5,d0
  1439.         move.l  #IC5,d1
  1440.         bsr     @WriteByte
  1441.  
  1442. sv_end  addq.l  #4,sp
  1443.         rts
  1444.  
  1445.  
  1446.  
  1447.  
  1448.  
  1449. *** The following routines are only for the 22V10 and/or 20RA10 GALs. ***
  1450.  
  1451.  
  1452.  
  1453. * SetPESSAVE:
  1454. * set PESSAVE pin (pin 4) of the GAL20RA10
  1455. * remark: this is routine is used for GAL22V10 only
  1456. * call: SetPESSAVE(pegel)
  1457. * parameter: pegel = HIGH or LOW
  1458.  
  1459. * SetERASE:
  1460. * set ERASE pin (pin 4) of the GAL22V10
  1461. * remark: this is routine is used for GAL22V10 only
  1462. * call: SetERASE(pegel)
  1463. * parameter: pegel = HIGH or LOW
  1464.  
  1465. @SetPESSAVE:
  1466. @SetERASE:
  1467.  
  1468.         cmp.l   #HW_ELEKTOR_II,_hw_version
  1469.         bne.s   ser_galer_hw
  1470.                                 ; *** elektor hardware ***
  1471.         and.l   #%01111111,_outIC4
  1472.         cmp.l   #LOW,d0
  1473.         beq.s   ser_c1
  1474.  
  1475.         or.l    #%10000000,_outIC4
  1476.         bra.s   ser_c1
  1477.  
  1478.  
  1479. ser_galer_hw                    ; *** GALer hardware ***
  1480.         and.l   #%11110111,_outIC4
  1481.         cmp.l   #LOW,d0
  1482.         beq.s   ser_c1
  1483.  
  1484.         or.l    #%00001000,_outIC4
  1485.  
  1486. ser_c1  move.l  #IC4,d1
  1487.         move.l  _outIC4,d0
  1488.         bsr     @WriteByte
  1489.  
  1490.         rts
  1491.  
  1492.  
  1493.  
  1494.  
  1495.  
  1496. * SetCLR:
  1497. * set CLR pin (pin 6) of GAL22V10 and GAL20RA10
  1498. * call: SetCLR(pegel)
  1499. * parameter: pegel = HIGH or LOW
  1500.  
  1501. @SetCLR:
  1502.  
  1503.         cmp.l   #HW_ELEKTOR_II,_hw_version
  1504.         bne.s   sclr_galer_hw
  1505.                                         ; *** elektor hardware ***
  1506.         and.l   #%11111011,_outIC4
  1507.         cmp.l   #LOW,d0
  1508.         beq.s   sclr_c1
  1509.         or.l    #%00000100,_outIC4
  1510.         bra.s   sclr_c1
  1511.  
  1512.  
  1513. sclr_galer_hw                           ; *** GALer hardware ***
  1514.         and.l   #%11011111,_outIC4
  1515.         cmp.l   #LOW,d0
  1516.         beq.s   sclr_c1
  1517.  
  1518.         or.l    #%00100000,_outIC4
  1519.  
  1520. sclr_c1 move.l  #IC4,d1
  1521.         move.l  _outIC4,d0
  1522.         bsr     @WriteByte
  1523.  
  1524.         rts
  1525.  
  1526.  
  1527.  
  1528.  
  1529.  
  1530. * SetBE:
  1531. * set BE pin (pin 7) of GAL22V10 and GAL20RA10
  1532. * call: SetBE(pegel)
  1533. * parameter: pegel = HIGH or LOW
  1534.  
  1535. @SetBE:
  1536.         cmp.l   #HW_ELEKTOR_II,_hw_version
  1537.         bne.s   sbe_galer_hw
  1538.                                         ; *** elektor hardware ***
  1539.         and.l   #%11011111,_outIC1
  1540.         cmp.l   #LOW,d0
  1541.         beq.s   sbe_c1
  1542.  
  1543.         or.l    #%00100000,_outIC1
  1544.  
  1545. sbe_c1  move.l  #IC1,d1
  1546.         move.l  _outIC1,d0
  1547.         bsr     @WriteByte
  1548.         bra.s   sbe_end
  1549.  
  1550.  
  1551. sbe_galer_hw                            ; *** GALer hardware ***
  1552.         and.l   #%10111111,_outIC4
  1553.         cmp.l   #LOW,d0
  1554.         beq.s   sbe_c2
  1555.  
  1556.         or.l    #%01000000,_outIC4
  1557.  
  1558. sbe_c2  move.l  #IC4,d1
  1559.         move.l  _outIC4,d0
  1560.         bsr     @WriteByte
  1561.  
  1562. sbe_end rts
  1563.  
  1564.  
  1565.  
  1566.  
  1567.  
  1568. * SetARCH:
  1569. * set ARCH pin (pin 8) of GAL22V10 and GAL20RA10
  1570. * call: SetARCH(pegel)
  1571. * parameter: pegel = HIGH or LOW
  1572.  
  1573. @SetARCH:
  1574.  
  1575.         cmp.l   #HW_ELEKTOR_II,_hw_version
  1576.         bne.s   sar_galer_hw
  1577.                                         ; *** elektor hardware ***
  1578.         and.l   #%11111110,_outIC1
  1579.         cmp.l   #LOW,d0
  1580.         beq.s   sar_c1
  1581.  
  1582.         or.l    #%00000001,_outIC1
  1583.  
  1584. sar_c1  move.l  #IC1,d1
  1585.         move.l  _outIC1,d0
  1586.         bsr     @WriteByte
  1587.         bra.s   sar_end
  1588.  
  1589. sar_galer_hw                            ; *** GALer hardware ***
  1590.         and.l   #%01111111,_outIC4
  1591.         cmp.l   #LOW,d0
  1592.         beq.s   sar_c2
  1593.  
  1594.         or.l    #%10000000,_outIC4
  1595.  
  1596. sar_c2  move.l  #IC4,d1
  1597.         move.l  _outIC4,d0
  1598.         bsr     @WriteByte
  1599.  
  1600. sar_end rts
  1601.  
  1602.  
  1603.  
  1604.  
  1605.  
  1606. * SetANDBE:
  1607. * set ANDBE pin (pin 9) of GAL20RA10
  1608. * remark: this routine is for the 22V10 GAL only
  1609. * call: SetCLR(pegel)
  1610. * parameter: pegel = HIGH or LOW
  1611.  
  1612. @SetANDBE:
  1613.  
  1614.         cmp.l   #HW_ELEKTOR_II,_hw_version
  1615.         bne.s   sand_galer_hw
  1616.                                         ; *** elektor hardware ***
  1617.         and.l   #%10111111,_outIC1
  1618.         cmp.l   #LOW,d0
  1619.         beq.s   sand_c1
  1620.  
  1621.         or.l    #%01000000,_outIC1
  1622.  
  1623. sand_c1 move.l  #IC1,d1
  1624.         move.l  _outIC1,d0
  1625.         bsr     @WriteByte
  1626.         bra.s   sand_end
  1627.  
  1628.  
  1629. sand_galer_hw                           ; *** GALer hardware ***
  1630.         and.l   #%11111110,_outIC5
  1631.         cmp.l   #LOW,d0
  1632.         beq.s   sand_c2
  1633.  
  1634.         or.l    #%00000001,_outIC5
  1635.  
  1636. sand_c2 move.l  #IC5,d1
  1637.         move.l  _outIC5,d0
  1638.         bsr     @WriteByte
  1639.  
  1640. sand_end
  1641.         rts
  1642.  
  1643.  
  1644.  
  1645.  
  1646.  
  1647.  
  1648.  
  1649.         SECTION data,DATA
  1650.  
  1651.  
  1652. _cia_timer_low:     dc.l    0       ; address of TxLO
  1653. _cia_timer_high:    dc.l    0       ; address of TxHI
  1654. _cia_timer_cr:      dc.l    0       ; address of CRx
  1655. _cia_timer_start:   dc.b    0       ; value to start cia timer
  1656. _cia_timer_stop:    dc.b    0       ; value to stop cia timer
  1657.  
  1658.  
  1659. _hw_version:        dc.l    0
  1660.  
  1661.  
  1662. cia_addrb:          dc.b    0
  1663. cia_bddra:          dc.b    0
  1664.  
  1665.  
  1666.         END
  1667.